var app = require('./config');

var debug = require('debug')('socket-mock-server:server');

const https = require('https');

var request = require('request');

var axios = require('axios');

var port = normalizePort(process.env.PORT || '7778');
app.set('port', port);

var http = require('http');
var server = http.createServer(app);


server.listen(port, function () {
    console.log('服务器：http://localhost:%s  已经开启', port);
});

server.on('error', onError);
server.on('listening', onListening);

var io = require('socket.io')(server);

//在线的socket对象  时间戳为key socket 为value
onlineSocketObj = {};

onlineDeviceObj = {};

// 在线mock数量
onlineMocks = 0;

//mock数据的集合
mockDataDic = {};

//当前mock的环境
currentMockEnvironment = {};

io.on('connection', function (socket) {

    console.log('新增了一个用户id为：', socket.id, ' 当前用户总数:', onlineMocks + 1);

    //增加一个mock用户
    socket.emit('login', socket.id);

    /**onlineSocketObj 数据结构
     *
     * socket.id ： socket
     */

    onlineSocketObj[socket.id] = socket;

    onlineMocks++;

    //用户选择的mock环境
    socket.on('userSelectMockEnv', function (env) {
        console.log('用户选择的mock环境', env,socket.id);

        /**
         * 环境改变 对应的socket.Id 对应的数据清空
         * */
         mockDataDic[socket.id] = {};

        /** currentMockEnvironment 数据结构
         * {
         * socket.id : https://sit.nonobank.com
         * }
         * */
        currentMockEnvironment[socket.id] = env;
    });

    //减少一个mock用户
    socket.on('disconnect', function () {
        console.log('减少了一个用户id为：', socket.id, ' 当前用户总数:', onlineMocks - 1);

        delete onlineSocketObj[socket.id];
        delete mockDataDic[socket.id];
        delete currentMockEnvironment[socket.id];
        onlineMocks--;
        // socket.emit('disconnect',true);
    });

    // 开启mock
    socket.on('mockDataMsg', function (data) {
        console.log('！！！！！！！来自客户端的数据---id', socket.id, data.mockKey, data.mockValue,data.mockTag);
        /**mockDataDic 数据结构
         * {
	     *  "socketid": {
		 *           "path": {
		 *               'data':{},
		 *              'mockTag':''
		 *           },
		 *           ...
	     *       }
         *      }
         * */
        try {
            if (mockDataDic[socket.id] === undefined) {
                mockDataDic[socket.id] = {};
                var dic1 = {
                    'data':data.mockValue,
                    'mockTag':data.mockTag
                };
                mockDataDic[socket.id][data.mockKey] = dic1;
            } else {
                var dic1 = {
                    'data':data.mockValue,
                    'mockTag':data.mockTag
                };
                mockDataDic[socket.id][data.mockKey] = dic1;
            }
            socket.emit('mockSucced', true);
        }
        catch (e) {
            socket.emit('mockSucced', false);
        }
    });

    //关闭mock
    socket.on('closeMock', function (data) {
        try {
            if (mockDataDic[socket.id] === undefined) {
                mockDataDic[socket.id] = {};
                socket.emit('closeMockSucced', false);
                return;
            }
            delete  mockDataDic[socket.id][data.mockKey];
            socket.emit('closeMockSucced', true);
        }
        catch (e) {
            socket.emit('closeMockSucced', false);
        }
    })

});

// mock接口的前缀
let mockPrex = '/mockIndex'

app.use(mockPrex, function (req, res, next) {

    /**
     * 获取设备信息
     * */
    let deviceIds = req.headers.deviceidentifier;

    /**
     * 注册设备
     * */
    if (req.path === '/uploadDeviceIdentifier') {
        let socketKey = req.query.socketKey;
        resistDevice(socketKey, deviceIds, res);
        return;
    }

    if (onlineDeviceObj[deviceIds] === undefined) {
        res.send({
            "errorMessage": "设备未注册",
            "errorCode": "0000001",
            "succeed": false,
            "data": null
        });
        return;
    }

    env = currentMockEnvironment[onlineDeviceObj[deviceIds].id];

    if (!env) {
        res.send({
            "errorMessage": "通话已失效，请重新扫描开始mock",
            "errorCode": "0000001",
            "succeed": false,
            "data": null
        });
        return;
    }

    /**
     *  post
     *  参数 body
     *  get
     *  参数 query
     * */
    let preStr = mockPrex + '/';
    /**
     * 请求转发
     * */
    let finalPath = env + req.originalUrl.substring(preStr.length)


    let data = {};
    if (req.method === 'GET') {
    } else if (req.method === 'POST') {
        data = req.body;
    }


    /**
     * 返回mock数据
     * */
    if (onlineDeviceObj[deviceIds] !== undefined) {
        mockSocketID = onlineDeviceObj[deviceIds].id;
        if (mockDataDic[mockSocketID] !== undefined &&
            mockDataDic[mockSocketID][req.path] !== undefined) {
            res.send(mockDataDic[mockSocketID][req.path]['data']);
            let obj = {
                method: req.method,
                url: finalPath,
                data: JSON.stringify(data),
                headers: req.headers,
                urlIdentification: req.path,
                timestamp:(new Date()).valueOf(),
            };

            messageSend(deviceIds, {
                config: obj,
                data: mockDataDic[mockSocketID][req.path]['data'],
                status: 200,
                isMock: true,
                mockTag:mockDataDic[mockSocketID][req.path]['mockTag']
            });
            return;
        }

    }

    /**
     * 发送真实请求
     * */

    delete  req.headers.host;
    console.log('2222',(new Date()).valueOf());
    axios({
        method: req.method,
        url: finalPath,
        data: data,
        headers:req.headers,
        // headers: {
        //     guid: req.headers.guid,
        //     apptype: req.headers.apptype,
        //     'user-agent': req.headers['user-agent'],
        //     ispinfo: req.headers.ispinfo,
        //     appbundleversion: req.headers.appbundleversion,
        //     appid: req.headers.appid,
        //     screenwidthpixel: req.headers.screenwidthpixel,
        //     comefrom: req.headers.comefrom,
        //     phonebrand: req.headers.phonebrand,
        //     userid: req.headers.userid,
        //     appversion: req.headers.appversion,
        //     screenheightpixel: req.headers.screenheightpixel,
        //     latitude: req.headers.latitude,
        //     deviceidentifier: req.headers.deviceidentifier,
        //     phonetype: req.headers.phonetype,
        //     version: req.headers.version,
        //     terminal: req.headers.terminal,
        //     appname: req.headers.appname,
        //     connection: req.headers.connection,
        //     longitude: req.headers.longitude,
        //     'accept-language': req.headers['accept-language'],
        //     authorization: req.headers.authorization,
        //     osversion: req.headers.osversion,
        //     appbuild: req.headers.appbuild,
        //     networktype: req.headers.networktype,
        //     osname: req.headers.osname,
        //     originid: req.headers.originid,
        //     accept: req.headers.accept,
        //     'accept-encoding': req.headers['accept-encoding']
        // },
        urlIdentification: req.path,
        httpsAgent: new https.Agent({
            rejectUnauthorized: false
        })
    })
        .then(function (response) {
            res.send(response.data);
            messageSend(deviceIds, {
                config: {
                    method: response.config.method,
                    url: response.config.url,
                    data: response.config.data,
                    headers: response.config.headers,
                    urlIdentification: response.config.urlIdentification,
                    timestamp : (new Date()).valueOf(),
                },
                data: response.data,
                status: response.status,
                isMock: false,
                mockTag:-1
            });
        })
        .catch(function (e) {
            try {
                res.sendStatus(e.response.status);
                messageSend(deviceIds, {
                    config: {
                        method: e.config.method,
                        url: e.config.url,
                        data: e.config.data,
                        headers: e.config.headers,
                        urlIdentification: e.config.urlIdentification,
                        timestamp : (new Date()).valueOf(),
                    },
                    data:{
                        statusText: e.response.statusText,
                        state: e.response.status,
                        Error: e.Error
                    },
                    status: e.response.status,
                    isMock: false,
                    mockTag:-1
                });

            }
            catch (error) {
                console.log('这是个错误', error);
            }
        });

});


// catch 404 and forward to error handler
app.use(function (req, res, next) {
    var err = new Error('Not Found');
    console.log('服务器的错误：', err);
    err.status = 404;
    next(err);
});

// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
});


function resistDevice(socketKey, deviceIds, res) {
    if (socketKey === undefined) {
        res.send({
            "errorCode": "0000001",
            "data": {
                "total": 0
            },
            "succeed": false,
            "errorMessage": "socketKey非法"
        });
        return;
    }

    if (onlineSocketObj[socketKey] === undefined) {
        res.send({
            "errorCode": "0000001",
            "data": {
                "total": 0
            },
            "succeed": false,
            "errorMessage": "该对象不存在"
        });
        return;
    }

    onlineDeviceObj[deviceIds] = onlineSocketObj[socketKey];

    res.send({
        "errorCode": "0000000",
        "data": {
            "total": 0
        },
        "succeed": true,
        "errorMessage": "操作成功"
    });
    onlineDeviceObj[deviceIds].emit('registDevice', true);
}

function messageSend(deviceIds, msg) {
    if (onlineDeviceObj[deviceIds] === undefined) {
        return;
    }
    onlineDeviceObj[deviceIds].emit('message', msg)
}

function normalizePort(val) {
    var port = parseInt(val, 10);

    if (isNaN(port)) {
        // named pipe
        return val;
    }

    if (port >= 0) {
        // port number
        return port;
    }

    return false;
}


function onError(error) {
    if (error.syscall !== 'listen') {
        throw error;
    }

    var bind = typeof port === 'string'
        ? 'Pipe ' + port
        : 'Port ' + port;

    // handle specific listen errors with friendly messages
    switch (error.code) {
        case 'EACCES':
            console.error(bind + ' requires elevated privileges');
            process.exit(1);
            break;
        case 'EADDRINUSE':
            console.error(bind + ' is already in use');
            process.exit(1);
            break;
        default:
            throw error;
    }
}

function onListening() {
    var addr = server.address();
    var bind = typeof addr === 'string'
        ? 'pipe ' + addr
        : 'port ' + addr.port;
    debug('Listening on ' + bind);
}

module.exports = app;
